package com.appcenter.jz.filter;

import com.appcenter.jz.app.CurrentUser;
import com.appcenter.jz.expandmodel.UserDetaileInfo;
import com.nimbusds.jwt.JWT;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.JWTParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

/**
 * Created by Administrator on 2019/3/17.
 */
@Component
public class JwtTokenFilter extends UsernamePasswordAuthenticationFilter {

	/**
	 * json web token 在请求头的名字
	 */
	@Value("${token.header}")
	private String tokenHeader;


	/**
	 * 辅助操作 token 的工具类
	 */
/*	@Autowired
	private JwtTokenUtils tokenUtils;*/

	@Autowired
	private SooUserService userDetailsService;

/*	@Autowired
	private JwtTokenUtils jwtTokenUtil;*/

	public JwtTokenFilter(AuthenticationManager authenticationManager) {
		setAuthenticationManager(authenticationManager);
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
		throws IOException, ServletException {

		// 将 ServletRequest 转换为 HttpServletRequest 才能拿到请求头中的 token
		HttpServletRequest httpRequest = (HttpServletRequest) request;

		HttpServletResponse rep = (HttpServletResponse) response;
		rep.setHeader("Access-Control-Allow-Origin", "*");
		//rep.setHeader("Access-Control-Allow-Methods","POST, GET, PUT, OPTIONS, DELETE, PATCH");
		//rep.setHeader("Access-Control-Max-Age", "3600");
		rep.setHeader("Access-Control-Allow-Headers","authorization,content-type");

		String method = httpRequest.getMethod();
		if (method.equals("OPTIONS")) {
			rep.setStatus(HttpServletResponse.SC_OK);
		}else {
			// 尝试获取请求头的 token
			String authToken = httpRequest.getHeader(this.tokenHeader);
			if (authToken == null || !authToken.startsWith("Bearer ")) {
				chain.doFilter(request, response);
				return;
			}
			System.out.println("getHeader(\"Authorization\")" + httpRequest.getHeader("Authorization"));
			// 尝试拿 token 中的 username
			// 若是没有 token 或者拿 username 时出现异常，那么 username 为 null
			String username = null;
			String userCode = null;
			String userId = null;
			Object orgs=null;
			String roles=null;
			Object roleLists=null;
			String token = httpRequest.getHeader("Authorization");
			try {
				JWT idToken = JWTParser.parse(authToken.replace("Bearer ", ""));
				JWTClaimsSet idClaims = idToken.getJWTClaimsSet();
				userCode = idClaims.getClaims().get("UserCode").toString();
				username = idClaims.getClaims().get("UserName").toString();
				userId = idClaims.getClaims().get("UserId").toString();
				orgs=idClaims.getClaims().get("Orgs");
				roles=idClaims.getClaims().get("Roles").toString();
				roleLists=idClaims.getClaims().get("http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
				//username = idClaims.getSubject();

			} catch (ParseException var31) {
				throw new AuthenticationServiceException("Couldn't parse idToken: ", var31);
			}

			//this.tokenUtils.getUsernameFromToken(authToken);

			// 如果上面解析 token 成功并且拿到了 username 并且本次会话的权限还未被写入
			if ((username != null) && (SecurityContextHolder.getContext().getAuthentication() == null)) {

				//UserDetaileInfo userDetails = this.userDetailsService.loadUserByUsername(username,userCode,userId);
				Collection<GrantedAuthority> authList = getAuthorities();

				UserDetaileInfo userDetails = new UserDetaileInfo(username, "password", userCode, userId, token, true, true, true, true, authList);
				userDetails.setOrgs(orgs);
				userDetails.setRoleLists(roleLists);
				userDetails.setRoles(roles);

				//if (this.tokenUtils.validateToken(authToken, userDetails)) {
				// 生成通过认证
				UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
				authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
				// 将权限写入本次会话
				SecurityContextHolder.getContext().setAuthentication(authentication);
				//}

			}
			chain.doFilter(request, response);
		}
	}


	/**  * 获取用户的角色权限,为了降低实验的难度，这里去掉了根据用户名获取角色的步骤     * @param    * @return   */
	private Collection<GrantedAuthority> getAuthorities(){
		List<GrantedAuthority> authList = new ArrayList<GrantedAuthority>();
		authList.add(new SimpleGrantedAuthority("ROLE_USER"));
		authList.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
		return authList;
	}
}
